
package com.jf.cloud.product.mapper;

import com.jf.cloud.common.order.bo.RefundReductionStockBO;
import com.jf.cloud.common.product.vo.SkuVO;
import com.jf.cloud.product.bo.SkuWithStockBO;
import com.jf.cloud.product.bo.SkuZoneInfoBO;
import com.jf.cloud.product.model.SkuStock;
import com.jf.cloud.product.vo.SkuStockVO;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * 库存信息
 *
 * @author zz
 * @date 2020-10-28 15:27:24
 */
public interface SkuStockMapper {

    /**
     * 更新库存信息
     * 该方法中库存的更新不使用set，使用加减法，是因为出入库或者其他地方要直接对主分片进行操作的时候就不用加锁了
     * @param skuStock 库存信息
     */
    void update(@Param("skuStock") SkuStock skuStock);

    /**
     * 批量保存
     * @param skuStocks 库存信息集合
     */
    void batchSave(@Param("skuStocks") List<SkuStock> skuStocks);

    /**
     * 批量添加库存
     * @param skuList 库存信息集合
     */
    void batchUpdateSkuStocks(@Param("SkuStockList") List<SkuStock> skuList);

    /**
     * 根据列表中的库存数量，增加sku的库存
     * @param skuStock 修改信息
     * @return 更新的数量
     */
    int updateStock(@Param("skuStock") SkuStock skuStock);

    /**
     * 通过订单减少库存
     * @param skuId 商品id
     * @param count 数量
     * @return
     */
    int reduceStockByOrder(@Param("skuId") Long skuId, @Param("count") Integer count);

    /**
     * 通过订单添加库存，扣除锁定库存
     * @param skuWithStock 库存信息
     */
    void addStockAndSubLockStockByOrder(@Param("skuWithStock") SkuWithStockBO skuWithStock);

    /**
     * 通过订单添加库存
     * @param skuWithStock
     */
    void addStockByOrder(@Param("skuWithStock") SkuWithStockBO skuWithStock);

    /**
     * 通过订单减少实际库存和锁定库存
     * @param skuWithStock 库存信息
     */
    void reduceActualStockByOrder(@Param("skuWithStock") SkuWithStockBO skuWithStock);

    /**
     * 通过订单减少锁定库存（已分片）
     * @param skuWithStock
     */
    void reduceLockStockByOrder(@Param("skuWithStock") SkuWithStockBO skuWithStock);

    /**
     * 通过已经取消的订单减少实际库存
     * @param skuWithStock 库存信息
     */
    void reduceActualStockByCancelOrder(@Param("skuWithStock") SkuWithStockBO skuWithStock);

    /**
     * 通过已经取消的订单减少库存(已分片)
     * @param skuWithStock 库存信息
     * @return
     */
    int reduceStockByCancelOrder(@Param("skuWithStock") SkuWithStockBO skuWithStock);

    /**
     * 还原sku实际库存
     * @param skuWithStock
     */
    void reductionActualStockByCancelOrder(@Param("skuWithStock") RefundReductionStockBO skuWithStock);

    /**
     * 还原sku分片库存
     * @param skuWithStock
     */
    void addStockByCancelOrder(@Param("skuWithStock") RefundReductionStockBO skuWithStock);

    /**
     * 根据商品id获取库存信息
     * @param spuId
     * @return
     */
    List<SkuStockVO> listStockBySpuId(@Param("spuId") Long spuId);

    /**
     * 获取指定sku的库存
     * @param skuId
     * @return
     */
    SkuStock getBySkuId(@Param("skuId") Long skuId);

    /**
     * 分片后的库存查询
     * @param skuId
     * @return
     */
    SkuStock getBySkuIdWhichZoned(@Param("skuId") Long skuId);

    /**
     * 更新商品库存（增加或减少库存）
     * @param skuId
     * @param stock 大于0：增加库存， 小于0：减少库存
     * @return 更新的条数
     */
    int updateSkuStock(@Param("skuId") Long skuId, @Param("stock") Integer stock);

    /**
     * 更新商品库存(分片后)（增加或减少库存）
     * @param skuId
     * @param stock 大于0：增加库存， 小于0：减少库存
     * @param zoneNum 更新后的可用分片数量
     * @return 更新的条数
     */
    int updateSkuStockWhenZone(@Param("skuId") Long skuId, @Param("stock") Integer stock, @Param("zoneNum") Integer zoneNum);

    /**
     * 是否有进行分片
     * @param skuId skuId
     * @return
     */
    SkuZoneInfoBO getZoneInfo(@Param("skuId") Long skuId);

    /**
     * 更新库存可用分片数量
     * @param skuId
     * @param limitZone
     */
    void updateLimitZone(@Param("skuId") Long skuId, @Param("limitZone") Integer limitZone);

    /**
     * 获取可用库存数量
     * @param skuId
     * @return
     */
    Integer getStock(@Param("skuId") Long skuId);

    /**
     * 根据商品id获取总主分片库存
     * @param spuId
     * @return
     */
    Integer getMainStockBySpuId(@Param("spuId") Long spuId);

    /**
     * 根据商品id获取总主分片的锁定库存
     * @param spuId
     * @return
     */
    Integer getLockStockBySpuId(@Param("spuId") Long spuId);

    /**
     * 根据skuId获取总主分片的锁定库存
     * @param skuId
     * @return
     */
    Integer getLockStockBySkuId(@Param("skuId") Long skuId);

    /**
     * 更新主分片库存和分片数量
     * 这里用减法不用set是因为出入库或者其他地方要直接对主分片进行操作的时候就不用加锁了
     * @param skuId
     * @param stock 用来分片的总库存
     * @param zoneNum
     */
    void updateStockAndLimitZone(@Param("skuId") Long skuId, @Param("stock") int stock, @Param("zoneNum") int zoneNum);

    /**
     * 更新主分片的库存和锁定库存和分片数量
     * @param skuId
     * @param stock 主分片扣减库存
     * @param lockStock 锁定库存
     * @param zoneNum
     */
    void updateStockAndLockStockAndLimitZone(@Param("skuId") Long skuId, @Param("stock") int stock,@Param("lockStock") int lockStock, @Param("zoneNum") int zoneNum);

    /**
     * 需要重新分片的sku
     * @param needZoneNum
     * @return
     */
    List<Long> listNeedReZoneSku(@Param("needZoneNum") int needZoneNum);

    /**
     * 通过供应商的spuId，获取商家对应的sku库存
     * @param spuId
     * @param shopId
     * @return
     */
    List<SkuStockVO> listShopStockBySpuIdAndShopId(@Param("spuId") Long spuId, @Param("shopId") Long shopId);

    /**
     * 更新sku为未分片的状态
     * @param skuId
     * @param stock
     * @param actualStock
     * @param lockStock
     */
    void updateSkuToUndoZone(@Param("skuId") Long skuId, @Param("stock") Integer stock, @Param("actualStock") Integer actualStock, @Param("lockStock") Integer lockStock);

    /**
     * 通过商品编码，获取商家对应的sku库存
     * @param partyCodes
     * @param shopId
     * @return
     */
    List<SkuStockVO> listShopStockByPartyCodesAndShopId(@Param("partyCodes") List<String> partyCodes,
                                                        @Param("shopId") Long shopId);
}
